/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { Reg } from './reg';
import { TmpBase } from './tmp_base';
import { Arg } from './arg';

export class Tmp extends TmpBase {
  index: number;
  _type: string;

  constructor(index: number, type: string) {
    super(type);
    this.index = index;
    this._type = type;
    super.type = this._type;
    super.isReg = false;
  }

  static fromReg(reg: TmpBase): Tmp {
    return reg as Tmp;
  }

  hash(): number {
    if (this.isGP) {
      return Reg.gprs[Reg.gprs.length - 1].hash() + 1 + this.index;
    } else {
      return Reg.fprs[Reg.fprs.length - 1].hash() - 1 - this.index;
    }
  }

  toString(): string {
    return `%${this.isGP ? '' : 'f'}tmp${this.index}`;
  }

  extract(arg: TmpBase): Tmp | null {
    let tmp = arg as Tmp;
    if (tmp !== null) {
      return tmp;
    } else {
      return null;
    }
  }

  static forEachFast(arg: Arg, fun: (reg: Reg) => Reg | null): Arg | null {
    return arg.forEachTmpFast(fun);
  }

  static forEach(arg: Arg, role: string, type: string, width: number, fun: (arg: Reg, role: string, type: string, width: number) => Reg | null): Arg | null {
    return arg.forEachTmp(role, type, width, fun);
  }
}
